package com.baichen;

import tech.medivh.classpy.classfile.MethodInfo;
import tech.medivh.classpy.classfile.bytecode.Instruction;
import tech.medivh.classpy.classfile.constant.ConstantPool;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

public class StackFrame {

    final MethodInfo methodInfo;
    final Object[] localVariables;
    final Deque<Object> operandStack;
    final List<Instruction> codes;
    final ConstantPool constantPool;
    int currentIndex;

    public StackFrame(MethodInfo methodInfo, ConstantPool constantPool, Object... args) {
        this.methodInfo = methodInfo;
        this.constantPool = constantPool;
        this.codes = methodInfo.getCodes();
        this.localVariables = new Object[methodInfo.getMaxLocals()];
        this.operandStack = new ArrayDeque<>();
        System.arraycopy(args, 0, localVariables, 0, args.length);
    }

    public Instruction getNextInstruction() {
        return codes.get(currentIndex++);
    }

    public void pushObjectToOperandStack(Object object) {
        operandStack.push(object);
    }

    public Object popObjectFromOperandStack() {
        return operandStack.pop();
    }

    public void jumpTo(int index) {
        for (int i = 0; i < codes.size(); i++) {
            if (codes.get(i).getPc() == index) {
                currentIndex = i;
                break;
            }
        }
    }
}
